
114
中包括一些分词器 。 现在你已经熟悉了正则表达式 , 你可以学习如何使用它们来为文本分词
,
并对此过程中有更多的掌控权。
分词的简单方法
文本分词的一种非常简单的方法是在空格符处分割文本 。 考虑以下摘自 《 爱丽丝梦游仙
境》中的文本:
>>> raw = """'When I'M a Duchess,' she said to herself, (not
in
a very hopeful tone
... though), 'I won't have any pepper
in
my kitchen
AT
ALL. Soup does very
... well without--Maybe it's always pepper that makes people hot-tempered,'..."""
我们可以使用 raw.split() 在空格符处分割原始文本 。 使用正则表达式能做同样的事情
,
匹配字符串中的所有空格符 是不够的 , 因为这将导致分词结果包含 “ \n ” 换行符 ; 我们需
要匹配任何数量的空格符、制表符或换行符 :
>>> re.split(r' ', raw)
["'When", "I'M", 'a', "Duchess,'", 'she', 'said', 'to', 'herself,', '(not', 'in',
'a', 'very', 'hopeful', 'tone\nthough),', "'I", "won't", 'have', 'any', 'pepper',
'in', 'my', 'kitchen', 'A T', 'ALL.', 'Soup', 'does', 'very\nwell', 'without--Maybe',
"it's", 'always', 'pepper', 'that', 'makes', 'people', "hot-tempered,'..."]
>>> re.split(r'[ \t\n]+', raw)
["'When", "I'M", 'a', "Duchess,'", 'she', 'said', 'to', 'herself,', '(not', 'in',
'a', 'very', 'hopeful', 'tone', 'though),', "'I", "won't", 'have', 'any', 'pepper',
'in', 'my', 'kitchen', 'A T', 'ALL.', 'Soup', 'does', 'very', 'well', 'without--Maybe',
"it's", 'always', 'pepper', 'that', 'makes', 'people', "hot-tempered,'..."]
正则表达式 «
[
\t\n]+ » 匹配一个或多个空格 、 制表符 ( \t ) 或换行符 ( \n ) 。 其他空白
字符 , 如回车和换页符 , 确实应该包含的太多 。 于是 , 我们将使用一个 re 库内置的缩写 “
\
s ” , 它表示匹配所有空白字符 。 前面的例子中第二条语句可以改写 为 re.split(r'\s+', raw) 。
要点: 记住在正则表达式前加字母 “ r ” ,它告诉 Python 解释器按照字面表示
对待字符串而不去处理正则表达式中包含的反斜杠字符。
在空格符处分割文本给我们如 “ (not ” 和 “ herself, ” 这样的标识符 。 另一种方法是使
用 Python 提供给我们的字符类 “ \w ” 匹配词中的字符,相当于 [a-zA-Z0-9_] 。也定义了
这个类的补 “ \W ” 即所有字母、数字和下划线以外的字符。我们可以在一个简单的正则表
达式中用 \W 来分割所有单词字符以外的输入。
>>> re.split(r'\W+', raw)
['', 'When', 'I', 'M', 'a', 'Duchess', 'she', 'said', 'to', 'herself', 'not', 'in',
'a', 'very', 'hopeful', 'tone', 'though', 'I', 'won', 't', 'have', 'any', 'pepper',
'in', 'my', 'kitchen', 'A T', 'ALL', 'Soup', 'does', 'very', 'well', 'without',
'Maybe', 'it', 's', 'always', 'pepper', 'that', 'makes', 'people', 'hot', 'tempered',
'']
可以看到 , 在开始和结尾都给了我们一个空字符串 ( 要了解原因请尝试 'xx'.split('x') )
。
通过 re.findall(r'\w+', raw) 使用模式匹配词汇而不是空白符号 , 我们得到相同的标识符
,
但没有空字符串 。 现在 , 我们正在匹配词汇 , 我们处在扩展正则表达式覆盖更广泛的情况的
位置 。 正则表达式 « \w+|\S\w* » 将首先尝试匹配词中字符的所有序列 。 如果没有找到匹配
的,它会尝试匹配后面跟着词中字符的任何非空白字符( “ \S ” 是 “ \s ” 的补 ) 。这意味着